const inquirer = require('inquirer')
const chalk = require('chalk')
const fs = require('fs')
const path = require('path')
const xlsx = require('node-xlsx')

//匹配中文字符
const chReg = /[\u4E00-\u9FA5]+/g
//匹配html注释
const chHtmlReg = /<!--.*-->/
/**
 * 多行注释匹配
 */
// const chJSRegMulti = /(?:^|\n|\r)\s*\/\*[\s\S]*?\*\/\s*(?:\r|\n|$)/g
const chJSRegMulti = /\s*\/\*[\s\S]*?\*\//g

//单行注释匹配
// const chJSRegSingle = /(?:^|\n|\r)\s*\/\/.*(?:\r|\n|$)/g
const chJSRegSingle = /\s*\/\/.*(?:\r|\n|$)/g

//去除注释 正则匹配
const noteReg = /\.(js|jsx|ts|tsx|cpp|wgsl|java|vue|json)$/
//去除html文件注释 正则匹配
const htmlReg = /\.(html|htm|xml)$/
let xlsxName = '项目中英文参照文档'
let xlsxPath = ''
let date = 0

//过滤规则数组
// const dirReg = /node_module|.git|wp.cofig/
let dirRegArr = ['node_module', '.git', 'wp.cfg', '.vscode', 'images', 'docs']
//xlsx表头
let chArr = [['文件名称', '中文', '英文']]
//用作记录检索文件类型和数量 {html: count,js:count}
let typeObject = {}

/**
 * 读取dir目录下文件目录
 * @param {*} dir 读取的目录
 */
function readDirSync(dir) {
  const dirRegStr =
    dirRegArr &&
    dirRegArr.length &&
    dirRegArr.reduce((preValue, value) => {
      return preValue ? preValue + '|' + value : value
    })
  const dirReg = new RegExp(dirRegStr)
  if (dir.match(dirReg)) {
    //过滤掉node_modules文件
    console.log(chalk.yellow('过滤文件------>' + dir))
    return
  }
  if (!dir) return
  const stats = fs.statSync(dir)
  if (stats.isDirectory()) {
    //如果是文件夹 递归调用readDir
    const filesArr = fs.readdirSync(dir)
    filesArr &&
      filesArr.length &&
      filesArr.map((file) => {
        //得到拼接目录
        const filePath = path.join(dir, file)
        readDirSync(filePath)
      })
  } else if (stats.isFile()) {
    readFileSync(dir)
  } else {
  }
}

/**
 * 同步读取文件
 * @param {*} filePath
 */
function readFileSync(filePath) {
  if (!filePath) return
  //图片 md文件 font字体文件过滤 文档过滤
  if (
    filePath.match(
      /\.(png|jpg|jpeg|md|gif|eot|otf|fon|font|ttf|ttc|woff|doc|docx|pdf|ppt|pptx|gz|zip|7z)$/
    )
  )
    return
  const extension = getExtension(filePath)
  if (typeObject[extension]) {
    //文件计数
    typeObject[extension].count = typeObject[extension].count + 1
  } else {
    typeObject[extension] = { count: 1 }
  }
  let fileData = fs.readFileSync(filePath, 'utf-8')
  if (!fileData) return
  let filterArr = []
  if (filePath.match(htmlReg)) {
    //过滤html注释
    fileData = fileData.replace(chHtmlReg, '')
  } else {
    fileData = fileData.replace(chJSRegMulti, '')
    fileData = fileData.replace(chJSRegSingle, '')
  }
  // if (filePath.match(noteReg)) {
  //过滤js|jsx注释
  // fileData = fileData.replace(chJSRegMulti, '')
  // fileData = fileData.replace(chJSRegSingle, '')
  // }
  const fileChArr = fileData.match(chReg)
  if (fileChArr && fileChArr.length > 0) {
    if (chArr.length !== 1) {
      //如果不是第一个页面添加空行
      chArr.push([null, null, null])
    }
    chArr.push([filePath, null, null])
    fileChArr.forEach((item) => {
      if (filterArr.indexOf(item) < 0) {
        //去重添加
        filterArr.push(item)
        chArr.push([filePath, item, null])
      }
    })
  }
  console.log(chalk.green(filePath + '文件检索完成'))
}

// 获取文件名
function getFileName(fileName) {
  return fileName.substring(0, fileName.lastIndexOf('.'))
}
// 获取 .后缀名
function getExtension(fileName) {
  return fileName.substring(fileName.lastIndexOf('.'))
}
// 只获取后缀名
function getExtension(fileName) {
  return fileName.substring(fileName.lastIndexOf('.') + 1)
}

/**
 * 脚本开始的方法
 * @param {*} filePath 项目目录path
 */
function readFilePathSync(filePath) {
  readDirSync(filePath)
  // chArr.push(['总计', JSON.stringify(typeObject), null])
  const sheetOptions = { '!cols': [{ wch: 50 }, { wch: 50 }, { wch: 50 }] }
  const buffer = xlsx.build([{ name: xlsxName, data: chArr }], {
    sheetOptions
  })
  const stats = fs.statSync(xlsxPath)
  if (stats.isFile()) {
    xlsxPath = path.resolve(xlsxPath, '..')
  }
  if (!fs.existsSync(xlsxPath + '/docs')) {
    //docs不存在就创建一个
    fs.mkdirSync(xlsxPath + '/docs')
  }
  // 写入xlsx文件
  fs.writeFileSync(xlsxPath + '/docs/' + xlsxName + '.xlsx', buffer, 'binary')
}

//简单指令 pathName 项目路径
function shellRun(pathName, isFilterDist = false) {
  pathName = Trim(pathName)
  try {
    xlsxPath = pathName
    if (isFilterDist) {
      dirRegArr.push('dist')
    }
    console.log(chalk.green('开始文件检索---------------------------------'))
    console.log(chalk.green('过滤文件列表------>' + JSON.stringify(dirRegArr)))
    date = new Date().getTime()
    readFilePathSync(pathName)
    console.log(
      chalk.green(
        '========================文件检索完成========================'
      )
    )
    if (!typeObject) return
    //统计检索文件类型 数量
    const keys = Object.keys(typeObject)
    if (keys && keys.length) {
      let total = 0,
        msg = ''
      keys.map((key, index) => {
        total = (total + typeObject[key] && typeObject[key].count) || 0
        msg =
          msg +
          `${key}文件:${(typeObject[key] && typeObject[key].count) || 0}\n`
      })
      msg = '总共检索文件:' + total + '\n' + msg
      console.log(chalk.blueBright(msg))
    }
    console.log(
      chalk.blueBright(
        '\nxlsx文件输出目录：' + xlsxPath + '/docs/' + xlsxName + '.xlsx'
      )
    )
    //统计花费时间
    console.log(chalk.yellow(`\n总用时:${new Date().getTime() - date}ms\n`))
  } catch (error) {
    //错误处理
    console.log(chalk.red('==============文件检索失败=============='))
    console.log(chalk.red('error:' + error))
  }
}

function autoRun() {
  //脚本命令开始的地方
  console.log(chalk.bold.cyan('\n欢迎使用交互式命令行工具\n'))
  //交互question数组
  const questions = [
    {
      type: 'input',
      name: 'projectPath',
      message: '项目地址：',
      filter: function (val) {
        if (val && !(val.indexOf("'") == -1)) {
          return Trim(val.replaceAll("'", ''))
        }
        return Trim(val)
      }
    },
    {
      type: 'confirm',
      name: 'filterDist',
      message: '是否过滤dist：',
      default: true
    },
    {
      type: 'input',
      name: 'filterRule',
      message: '自定义过滤目录用,隔开(eg:dist,images)：'
    },
    {
      type: 'input',
      name: 'xlsxPath',
      message: 'xlsx路径(默认项目docs下)：'
    },
    {
      type: 'input',
      name: 'xlsxName',
      message: 'xlsx名称：',
      default: xlsxName
    },
    {
      type: 'confirm',
      name: 'confirm',
      message: '确定开始(默认y)?',
      default: true
    }
  ]

  //question交互
  inquirer
    .prompt(questions)
    .then((res) => {
      if (!res) console.log(chalk.red('参数错误，请重试！'))
      if (!res.confirm) console.log(chalk.gray('取消了检索操作！'))
      if (!res.projectPath) console.log(chalk.gray('文件目录为空!'))
      //设置过滤规则
      if (res.filterDist) {
        dirRegArr.push('dist')
      }
      if (res.filterRule) {
        dirRegArr.push(...(res.filterRule && res.filterRule.split(',')))
      }
      //赋值xlsx输出目录
      if (res.xlsxPath) {
        xlsxPath = res.xlsxPath
      } else {
        xlsxPath = res.projectPath
      }
      //赋值xlsx名称
      if (res.xlsxName) {
        xlsxName = res.xlsxName
      }
      console.log(chalk.green('开始文件检索---------------------------------'))
      console.log(
        chalk.green('过滤文件列表------>' + JSON.stringify(dirRegArr))
      )
      date = new Date().getTime()
      readFilePathSync(res.projectPath)
      console.log(
        chalk.green(
          '========================文件检索完成========================'
        )
      )
      if (!typeObject) return
      //统计检索文件类型 数量
      const keys = Object.keys(typeObject)
      if (keys && keys.length) {
        let total = 0,
          msg = ''
        keys.map((key, index) => {
          total = (total + typeObject[key] && typeObject[key].count) || 0
          msg =
            msg +
            `${key}文件:${(typeObject[key] && typeObject[key].count) || 0}\n`
        })
        msg = '总共检索文件:' + total + '\n' + msg
        console.log(chalk.blueBright(msg))
      }
      console.log(
        chalk.blueBright(
          '\nxlsx文件输出目录：' + xlsxPath + '/docs/' + xlsxName + '.xlsx'
        )
      )
      //统计花费时间
      console.log(chalk.yellow(`\n总用时:${new Date().getTime() - date}ms\n`))
    })
    .catch((e) => {
      //错误处理
      console.log(chalk.red('==============文件检索失败=============='))
      console.log(chalk.red('error:' + e))
    })
}

function Trim(str) {
  return str.replace(/(^\s*)|(\s*$)/g, '')
}

// node项目执行请打开
// autoRun()

module.exports = { shellRun, autoRun }
